/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Editor.java
 *
 * Created on 21.12.2010, 01:34:12
 */

package editor;

import javax.swing.JFrame;
import java.awt.*;
import java.io.*;
import java.util.zip.*;
import game.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.imageio.ImageIO;

public class Editor extends JFrame {

    // DEFINITIONS (DO NOT CHANGE!):

    public static final int DRAW = 0;
    public static final int ERASE = 1;
    public static final int SELECT = 2;

    // DEFINITIONS END

    public static int tab;

    public static int drawMode = DRAW;

    public static int cameraPrefHeight;
    public static int cameraTolerance;

    public static javax.swing.JFrame toolbox;
    public static boolean toolboxVisible = false;

    public static javax.swing.JFrame objectListEditor;
    
    public static javax.swing.JFrame tilePropertiesEditor;

    public static javax.swing.JFrame about;

    public static javax.swing.JFrame mapEdit;

    public static javax.swing.JFrame newMapWindow;

    public static javax.swing.JFrame tryGame;

    public static Dimension maxSize = new Dimension(0,0);
    public static Dimension minSize = new Dimension(48,48);

    public static String[] gameObjectList;

    public static Level loadedLevel = new Level("");

    public static Map map;

    public static GameObject selectedObject = null;

    public static boolean[] keyPressed = new boolean[99999];
    public static boolean[] keyReleased = new boolean[99999];

    public Editor() {

        initComponents();
        addComponentListener(resizeListener);
        addKeyListener(new KeyPressListener());

    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        createNewMapFrame = new javax.swing.JFrame();
        jButton1 = new javax.swing.JButton();
        jSpinner1 = new javax.swing.JSpinner();
        jSpinner2 = new javax.swing.JSpinner();
        jSplitPane1 = new javax.swing.JSplitPane();
        jLabel1 = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        jToolBar1 = new javax.swing.JToolBar();
        NewButton = new javax.swing.JButton();
        OpenButton = new javax.swing.JButton();
        SaveButton = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        DrawButton1 = new javax.swing.JButton();
        EraseButton = new javax.swing.JButton();
        DrawButton = new javax.swing.JButton();
        MagicButton = new javax.swing.JButton();
        jSeparator2 = new javax.swing.JToolBar.Separator();
        ToolsButton = new javax.swing.JButton();
        GridButton = new javax.swing.JButton();
        BackgroundButton = new javax.swing.JButton();
        CameraButton = new javax.swing.JButton();
        jSeparator3 = new javax.swing.JToolBar.Separator();
        TestButton = new javax.swing.JButton();
        jPanel2 = new javax.swing.JPanel();
        EditorModeLabel = new javax.swing.JLabel();
        mainPanel = new javax.swing.JPanel();
        MapScrollPane = new javax.swing.JScrollPane();
        MapPanel = map = new Map();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu fileMenu = new javax.swing.JMenu();
        NewMenuItem = new javax.swing.JMenuItem();
        OpenMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenuItem SaveMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        WindowMenu = new javax.swing.JMenu();
        toolsCheckBox = new javax.swing.JCheckBoxMenuItem();
        gridCheckBox = new javax.swing.JCheckBoxMenuItem();
        bgLayerCheckBox = new javax.swing.JCheckBoxMenuItem();
        cameraCheckBox = new javax.swing.JCheckBoxMenuItem();
        jMenu1 = new javax.swing.JMenu();
        jMenuItem4 = new javax.swing.JMenuItem();

        createNewMapFrame.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        createNewMapFrame.setTitle("New Map");
        createNewMapFrame.setAlwaysOnTop(true);
        createNewMapFrame.setMinimumSize(new java.awt.Dimension(151, 100));
        createNewMapFrame.setName("createNewMapFrame"); // NOI18N
        createNewMapFrame.setResizable(false);
        createNewMapFrame.setSize(new java.awt.Dimension(164, 100));

        jButton1.setText("OK");
        jButton1.setName("jButton1"); // NOI18N
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jSpinner1.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        jSpinner1.setName("jSpinner1"); // NOI18N
        jSpinner1.setValue(10);
        jSpinner1.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                jSpinner1PropertyChange(evt);
            }
        });

        jSpinner2.setName("jSpinner2"); // NOI18N
        jSpinner2.setValue(10);

        org.jdesktop.layout.GroupLayout createNewMapFrameLayout = new org.jdesktop.layout.GroupLayout(createNewMapFrame.getContentPane());
        createNewMapFrame.getContentPane().setLayout(createNewMapFrameLayout);
        createNewMapFrameLayout.setHorizontalGroup(
            createNewMapFrameLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(createNewMapFrameLayout.createSequentialGroup()
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .add(createNewMapFrameLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, createNewMapFrameLayout.createSequentialGroup()
                        .add(jSpinner1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 56, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(34, 34, 34)
                        .add(jSpinner2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 56, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap())
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, createNewMapFrameLayout.createSequentialGroup()
                        .add(jButton1)
                        .add(54, 54, 54))))
        );
        createNewMapFrameLayout.setVerticalGroup(
            createNewMapFrameLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(createNewMapFrameLayout.createSequentialGroup()
                .addContainerGap()
                .add(createNewMapFrameLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jSpinner1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jSpinner2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(jButton1)
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jSplitPane1.setName("jSplitPane1"); // NOI18N

        jLabel1.setText("   Editor Mode: ");
        jLabel1.setAlignmentY(0.0F);
        jLabel1.setName("jLabel1"); // NOI18N

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Map Editor");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        jPanel1.setName("jPanel1"); // NOI18N

        jToolBar1.setFloatable(false);
        jToolBar1.setRollover(true);
        jToolBar1.setName("jToolBar1"); // NOI18N

        NewButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/editor/resources/document-new.png"))); // NOI18N
        NewButton.setToolTipText("New Level");
        NewButton.setBorder(null);
        NewButton.setName("NewButton"); // NOI18N
        NewButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                NewButtonActionPerformed(evt);
            }
        });
        jToolBar1.add(NewButton);

        OpenButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/editor/resources/document-open.png"))); // NOI18N
        OpenButton.setToolTipText("Open Level");
        OpenButton.setBorder(null);
        OpenButton.setName("OpenButton"); // NOI18N
        OpenButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                OpenButtonActionPerformed(evt);
            }
        });
        jToolBar1.add(OpenButton);

        SaveButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/editor/resources/save.png"))); // NOI18N
        SaveButton.setToolTipText("Save Level");
        SaveButton.setBorder(null);
        SaveButton.setName("SaveButton"); // NOI18N
        SaveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SaveButtonActionPerformed(evt);
            }
        });
        jToolBar1.add(SaveButton);
        jToolBar1.add(jSeparator1);

        DrawButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/editor/resources/select.png"))); // NOI18N
        DrawButton1.setToolTipText("Select");
        DrawButton1.setBorder(null);
        DrawButton1.setFocusable(false);
        DrawButton1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        DrawButton1.setName("DrawButton1"); // NOI18N
        DrawButton1.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        DrawButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DrawButton1ActionPerformed(evt);
            }
        });
        jToolBar1.add(DrawButton1);

        EraseButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/editor/resources/draw-eraser.png"))); // NOI18N
        EraseButton.setToolTipText("Rubber");
        EraseButton.setBorder(null);
        EraseButton.setFocusable(false);
        EraseButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        EraseButton.setName("EraseButton"); // NOI18N
        EraseButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        EraseButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                EraseButtonActionPerformed(evt);
            }
        });
        jToolBar1.add(EraseButton);

        DrawButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/editor/resources/draw.png"))); // NOI18N
        DrawButton.setToolTipText("Draw");
        DrawButton.setBorder(null);
        DrawButton.setName("DrawButton"); // NOI18N
        DrawButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DrawButtonActionPerformed(evt);
            }
        });
        jToolBar1.add(DrawButton);

        MagicButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/editor/resources/magic.png"))); // NOI18N
        MagicButton.setToolTipText("sort tiles \"magically\"...");
        MagicButton.setBorder(null);
        MagicButton.setFocusable(false);
        MagicButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        MagicButton.setName("MagicButton"); // NOI18N
        MagicButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        MagicButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MagicButtonActionPerformed(evt);
            }
        });
        jToolBar1.add(MagicButton);

        jSeparator2.setName("jSeparator2"); // NOI18N
        jToolBar1.add(jSeparator2);

        ToolsButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/editor/resources/toolbox.png"))); // NOI18N
        ToolsButton.setToolTipText("Toggle Tools Window");
        ToolsButton.setBorder(null);
        ToolsButton.setFocusable(false);
        ToolsButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ToolsButton.setName("ToolsButton"); // NOI18N
        ToolsButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ToolsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ToolsButtonActionPerformed(evt);
            }
        });
        jToolBar1.add(ToolsButton);

        GridButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/editor/resources/grid.png"))); // NOI18N
        GridButton.setToolTipText("Toggle Grid");
        GridButton.setBorder(null);
        GridButton.setFocusable(false);
        GridButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        GridButton.setName("GridButton"); // NOI18N
        GridButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        GridButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                GridButtonActionPerformed(evt);
            }
        });
        jToolBar1.add(GridButton);

        BackgroundButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/editor/resources/drawbg.png"))); // NOI18N
        BackgroundButton.setToolTipText("Toggle Background");
        BackgroundButton.setBorder(null);
        BackgroundButton.setFocusable(false);
        BackgroundButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        BackgroundButton.setName("BackgroundButton"); // NOI18N
        BackgroundButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        BackgroundButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                BackgroundButtonActionPerformed(evt);
            }
        });
        jToolBar1.add(BackgroundButton);

        CameraButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/editor/resources/camera.png"))); // NOI18N
        CameraButton.setToolTipText("Toggle Camera");
        CameraButton.setBorder(null);
        CameraButton.setFocusable(false);
        CameraButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        CameraButton.setName("CameraButton"); // NOI18N
        CameraButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        CameraButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                CameraButtonActionPerformed(evt);
            }
        });
        jToolBar1.add(CameraButton);

        jSeparator3.setName("jSeparator3"); // NOI18N
        jToolBar1.add(jSeparator3);

        TestButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/editor/resources/go-next.png"))); // NOI18N
        TestButton.setToolTipText("Try Map");
        TestButton.setBorder(null);
        TestButton.setFocusable(false);
        TestButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        TestButton.setName("TestButton"); // NOI18N
        TestButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        TestButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                TestButtonActionPerformed(evt);
            }
        });
        jToolBar1.add(TestButton);

        jPanel2.setName("jPanel2"); // NOI18N

        EditorModeLabel.setText("Editor Mode: Draw");
        EditorModeLabel.setName("EditorModeLabel"); // NOI18N

        org.jdesktop.layout.GroupLayout jPanel2Layout = new org.jdesktop.layout.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel2Layout.createSequentialGroup()
                .addContainerGap(154, Short.MAX_VALUE)
                .add(EditorModeLabel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 132, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(EditorModeLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 33, Short.MAX_VALUE)
        );

        jToolBar1.add(jPanel2);

        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jToolBar1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 711, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jToolBar1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 37, Short.MAX_VALUE)
        );

        mainPanel.setName("mainPanel"); // NOI18N

        MapScrollPane.setBorder(null);
        MapScrollPane.setMinimumSize(new java.awt.Dimension(0, 0));
        MapScrollPane.setName("MapScrollPane"); // NOI18N
        MapScrollPane.setPreferredSize(new java.awt.Dimension(586, 447));

        MapPanel.setName("MapPanel"); // NOI18N

        org.jdesktop.layout.GroupLayout MapPanelLayout = new org.jdesktop.layout.GroupLayout(MapPanel);
        MapPanel.setLayout(MapPanelLayout);
        MapPanelLayout.setHorizontalGroup(
            MapPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 1054, Short.MAX_VALUE)
        );
        MapPanelLayout.setVerticalGroup(
            MapPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 572, Short.MAX_VALUE)
        );

        MapScrollPane.setViewportView(MapPanel);

        org.jdesktop.layout.GroupLayout mainPanelLayout = new org.jdesktop.layout.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, MapScrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 711, Short.MAX_VALUE)
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, MapScrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 486, Short.MAX_VALUE)
        );

        menuBar.setBackground(new java.awt.Color(153, 153, 153));
        menuBar.setBorder(null);
        menuBar.setName("menuBar"); // NOI18N

        fileMenu.setBackground(new java.awt.Color(153, 153, 153));
        fileMenu.setText("File");
        fileMenu.setName("fileMenu"); // NOI18N

        NewMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.event.InputEvent.CTRL_MASK));
        NewMenuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/editor/resources/document-new-16.png"))); // NOI18N
        NewMenuItem.setText("New");
        NewMenuItem.setName("NewMenuItem"); // NOI18N
        NewMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                NewMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(NewMenuItem);

        OpenMenuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/editor/resources/document-open-16.png"))); // NOI18N
        OpenMenuItem.setText("Open");
        OpenMenuItem.setName("OpenMenuItem"); // NOI18N
        OpenMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                OpenMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(OpenMenuItem);

        SaveMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        SaveMenuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/editor/resources/save-16.png"))); // NOI18N
        SaveMenuItem.setText("Save");
        SaveMenuItem.setName("SaveMenuItem"); // NOI18N
        SaveMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SaveMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(SaveMenuItem);

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance().getContext().getActionMap(Editor.class, this);
        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        WindowMenu.setBackground(new java.awt.Color(153, 153, 153));
        WindowMenu.setText("Window");
        WindowMenu.setName("WindowMenu"); // NOI18N

        toolsCheckBox.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_T, java.awt.event.InputEvent.CTRL_MASK));
        toolsCheckBox.setText("Tools");
        toolsCheckBox.setName("toolsCheckBox"); // NOI18N
        toolsCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                toolsCheckBoxActionPerformed(evt);
            }
        });
        WindowMenu.add(toolsCheckBox);

        gridCheckBox.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_G, java.awt.event.InputEvent.CTRL_MASK));
        gridCheckBox.setSelected(true);
        gridCheckBox.setText("Show Grid");
        gridCheckBox.setName("gridCheckBox"); // NOI18N
        WindowMenu.add(gridCheckBox);

        bgLayerCheckBox.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_B, java.awt.event.InputEvent.CTRL_MASK));
        bgLayerCheckBox.setText("Show Background Layer");
        bgLayerCheckBox.setName("bgLayerCheckBox"); // NOI18N
        WindowMenu.add(bgLayerCheckBox);

        cameraCheckBox.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.CTRL_MASK));
        cameraCheckBox.setText("Show Camera");
        cameraCheckBox.setName("cameraCheckBox"); // NOI18N
        WindowMenu.add(cameraCheckBox);

        menuBar.add(WindowMenu);

        jMenu1.setBackground(new java.awt.Color(153, 153, 153));
        jMenu1.setText("Help");
        jMenu1.setName("jMenu1"); // NOI18N

        jMenuItem4.setText("About ...");
        jMenuItem4.setName("AboutMenuItem"); // NOI18N
        jMenuItem4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem4ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem4);

        menuBar.add(jMenu1);

        setJMenuBar(menuBar);

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .add(mainPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(mainPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

        public static boolean copyFile(File src, File dest) throws IOException{

        if(!src.equals(dest)){
            FileInputStream fis  = new FileInputStream(src);
            FileOutputStream fos = new FileOutputStream(dest);
            try {
                byte[] buf = new byte[1024];
                int i = 0;
                while ((i = fis.read(buf)) != -1) {
                    fos.write(buf, 0, i);
                }
            }
            catch (Exception e) {
                System.out.println("ERROR copying files: " + e);
            }
            finally {
                if (fis != null) fis.close();
                if (fos != null) fos.close();
            }
            return true;
        }
        return false;

    }
    private class KeyPressListener extends KeyAdapter {
        //key down event:
        @Override
        public void keyPressed(KeyEvent e){
            int key = e.getKeyCode();
            if(keyPressed[key] == false){
                keyPressed[key] = true;
                System.out.println(key);
            }

        }

        //key up event:
        @Override
        public void keyReleased(KeyEvent e){
            int key = e.getKeyCode();
            keyReleased[key] = true;
            keyPressed[key] = false;
        }

    }

    private void NewMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_NewMenuItemActionPerformed
        Map.clear();
        createNewMapFrame.setVisible(true);
}//GEN-LAST:event_NewMenuItemActionPerformed

    private void SaveMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SaveMenuItemActionPerformed

        saveLevel(gameMain.FileSaveDialog("Save..."));

}//GEN-LAST:event_SaveMenuItemActionPerformed

    private void OpenMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_OpenMenuItemActionPerformed
    
    loadLevel(gameMain.FileOpenDialog("Open..."));

}//GEN-LAST:event_OpenMenuItemActionPerformed

    private void toolsCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_toolsCheckBoxActionPerformed
        toolbox.setVisible(toolsCheckBox.getState());
}//GEN-LAST:event_toolsCheckBoxActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        Toolbox.mapWidthSpinner.setValue(jSpinner1.getValue());
        Toolbox.mapHeightSpinner.setValue(jSpinner1.getValue());

        Editor.map.setMapSize(Integer.parseInt(jSpinner1.getValue().toString())*16,Integer.parseInt(jSpinner2.getValue().toString())*16);
        createNewMapFrame.dispose();
}//GEN-LAST:event_jButton1ActionPerformed

    private void jSpinner1PropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_jSpinner1PropertyChange
        if (Integer.parseInt(jSpinner2.getValue().toString())<0){
            jSpinner2.setValue("0");
        }
        if (Integer.parseInt(jSpinner2.getValue().toString())>999){
            jSpinner2.setValue("999");
        }
        if (Integer.parseInt(jSpinner1.getValue().toString())<0){
            jSpinner2.setValue("0");
        }
        if (Integer.parseInt(jSpinner1.getValue().toString())>999){
            jSpinner2.setValue("999");
        }
}//GEN-LAST:event_jSpinner1PropertyChange

    public static ComponentListener resizeListener = new ComponentAdapter(){

        @Override
        public void componentResized(ComponentEvent evt) {

            //get component
            Component c = (Component)evt.getSource();

            boolean maxwidth = c.getSize().width >= maxSize.width;
            boolean maxheight = c.getSize().height >= maxSize.height + 48;

            //resize component if too big:
            if(c.getSize().height > maxSize.height && maxSize.height >= minSize.height){
                if(maxwidth){
                    c.setSize(c.getWidth(), maxSize.height + 30);
                }
                else{
                    c.setSize(c.getWidth(), maxSize.height + 45);
                }
            }

            if(c.getSize().width > maxSize.width && maxSize.width >= minSize.width){
                if(maxheight){
                    c.setSize(maxSize.width, c.getHeight() + 30);
                }
                else{
                    c.setSize(maxSize.width + 30, c.getHeight() + 45);
                }
            }

            //resize if too small:
            if(c.getSize().height < minSize.height){
                c.setSize(c.getWidth(), minSize.height);
            }

            if(c.getSize().width < minSize.width){
                c.setSize(minSize.width, c.getHeight());
            }


        }
    };


    @Override
    public void setMaximumSize(Dimension maximumSize) {
        maxSize = maximumSize;
    }


    public static void setAbout(JFrame about) {
        Editor.about = about;
    }

    private void jMenuItem4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem4ActionPerformed
        about.setVisible(true);
    }//GEN-LAST:event_jMenuItem4ActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        new Level("").clean();
    }//GEN-LAST:event_formWindowClosing

    private void NewButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_NewButtonActionPerformed
        newMapWindow.setVisible(true);
    }//GEN-LAST:event_NewButtonActionPerformed

    private void OpenButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_OpenButtonActionPerformed
        loadLevel(gameMain.FileOpenDialog("Open..."));
    }//GEN-LAST:event_OpenButtonActionPerformed

    private void ToolsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ToolsButtonActionPerformed
        toolsCheckBox.setSelected(!toolsCheckBox.getState());
        toolbox.setVisible(toolsCheckBox.getState());
    }//GEN-LAST:event_ToolsButtonActionPerformed

    private void GridButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_GridButtonActionPerformed
        gridCheckBox.setSelected(!gridCheckBox.getState());
    }//GEN-LAST:event_GridButtonActionPerformed

    private void BackgroundButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_BackgroundButtonActionPerformed
        bgLayerCheckBox.setSelected(!bgLayerCheckBox.getState());
    }//GEN-LAST:event_BackgroundButtonActionPerformed

    private void CameraButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CameraButtonActionPerformed
        cameraCheckBox.setSelected(!cameraCheckBox.getState());
    }//GEN-LAST:event_CameraButtonActionPerformed

    private void MagicButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MagicButtonActionPerformed
        map.sortTiles();
}//GEN-LAST:event_MagicButtonActionPerformed

    private void DrawButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DrawButton1ActionPerformed
        
        drawMode = SELECT;
        EditorModeLabel.setText("Editor Mode: Select");

    }//GEN-LAST:event_DrawButton1ActionPerformed

    private void DrawButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DrawButtonActionPerformed

        drawMode = DRAW;
        EditorModeLabel.setText("Editor Mode: Draw");

    }//GEN-LAST:event_DrawButtonActionPerformed

    private void EraseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_EraseButtonActionPerformed

        drawMode = ERASE;
        EditorModeLabel.setText("Editor Mode: Erase");

    }//GEN-LAST:event_EraseButtonActionPerformed

    private void SaveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SaveButtonActionPerformed
        saveLevel(gameMain.FileSaveDialog("Save..."));
    }//GEN-LAST:event_SaveButtonActionPerformed

    private void TestButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_TestButtonActionPerformed
        saveLevel(new File("test.temp"));
        
        if(tryGame == null){
            tryGame = new Main("test.temp");
        }
        else{tryGame.setVisible(true);
            Main.GAME.loadLevel(new File("test.temp"));
            Main.GAME.renderTileLayer();
            Main.GAME.renderBackgroundLayer(0);
            Main.GAME.renderBackgroundLayer(1);
        }

        tryGame.setVisible(true);
    }//GEN-LAST:event_TestButtonActionPerformed

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                mapEdit = new Editor();
                mapEdit.setVisible(true);
            }
        });

        toolbox = new Toolbox();
        toolbox.setVisible(false);

        about = new MapEditorAbout();
        about.setVisible(false);

        newMapWindow = new NewDialog();
        newMapWindow.setVisible(false);

        objectListEditor = new ObjectListEditor();
        objectListEditor.setVisible(false);

        tilePropertiesEditor = new TilePropertiesEditor();
        tilePropertiesEditor.setVisible(false);
        tryGame = null;
        //tryGame.setVisible(false);
    }

    public static void saveLevel(File file){

        if(file != null){

            int h = Map.maxHeight/16;
            int w = Map.maxWidth/16;

            //Check if file already exists is done by the awt file dialog already.

            //Create the level file
            File levelFile = new File("level");
            if(levelFile.exists()){
                System.out.println("level already exists");
            }

            String str="";

            try{
                FileWriter fw = new FileWriter(levelFile);
                for (int y = 0; y < h; y++){
                    for (int x = 0; x < w; x++){
                        if (Map.object[Map.getObjectNumberAt(new Point(x,y))] != null){
                            str += "" + Map.object[Map.getObjectNumberAt(new Point(x,y))].objectChar;
                        } else{
                            str += " ";
                        }
                    }
                    str += "\n";
                }
                fw.write(str);
                fw.close();
            } catch(Exception e){
                System.out.println("ERROR saving level file: " + e);
            }

            //create properties file
            File propertiesFile = new File("properties");
            if(propertiesFile.exists()){
                System.out.println("properties file already exists");
            }
            str="";
            try{
                FileWriter fw = new FileWriter(propertiesFile);

                str += "cameraPrefHeight = " + cameraPrefHeight + "\n";
                str += "cameraTolerance = " + cameraTolerance + "\n";
                str += "\n";

                fw.write(str);
                fw.close();
            } catch(Exception e){
                System.out.println("ERROR saving properties file: " + e);
            }

            //create objects file
            File objectsFile = new File("objects");
            if(objectsFile.exists()){
                System.out.println("objects file already exists");
            }
            str="";
            try{
                FileWriter fw = new FileWriter(objectsFile);

                for(int i = 0; i < Toolbox.objectChooser.objectList.length; i++){
                    str += Toolbox.objectChooser.objectList[i].toString() + "\n";
                }

                fw.write(str);
                fw.close();
            } catch(Exception e){
                System.out.println("ERROR saving objects file: " + e);
            }

            try{
                copyFile(new File(Toolbox.bg0TextField.getText()), new File("bg0.png"));
                copyFile(new File(Toolbox.bg1TextField.getText()), new File("bg1.png"));
                copyFile(new File(Toolbox.tilesheetTextField.getText()), new File("tilesheet.png"));
            }
            catch(Exception e){
                System.out.println("ERROR copying files: " + e);
            }

            // Add files to achrive
            String filenames[] = {
                "level",
                "tilesheet.png",
                "bg0.png",
                "bg1.png",
                "properties",
                "objects"
            };

            // Create a buffer for reading the files
            byte[] buf = new byte[1024];

            try {
                // Create the ZIP file
                String outFilename = file.getPath();
                ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outFilename));

                // Compress the files
                for (int i=0; i<filenames.length; i++) {
                    FileInputStream in = new FileInputStream(filenames[i]);

                    // Add ZIP entry to output stream.
                    out.putNextEntry(new ZipEntry(filenames[i]));

                    // Transfer bytes from the file to the ZIP file
                    int len;
                    while ((len = in.read(buf)) > 0) {
                        out.write(buf, 0, len);
                    }

                    // Complete the entry
                    out.closeEntry();
                    in.close();
                }

                // Complete the ZIP file
                out.close();

                // Delete the created loadedLevel file
                levelFile.delete();
            } catch (IOException e) {
                System.out.println("ERROR saving level archive: " + e);
            }

            new File("level").delete();
            new File("properties").delete();
            new File("objects").delete();

            System.out.println("Saving was successful!");

            
        }
        else{
            System.out.println("Saving cancelled...");
        }
    }

    public static void loadLevel(File file){
        
        if(file != null){

            //clean up old loads:
            loadedLevel.clean();

            loadedLevel = new Level(file.getPath());

            Camera camera = null;

            try{
                camera = loadedLevel.getCamera();
                Toolbox.objectChooser.objectList = loadedLevel.getGameObjects();
                
                //check if inside JAR (this enables loading of ALL possible objects in the game
                if(new File(Editor.class.getProtectionDomain().getCodeSource().getLocation().toURI()).exists()){
                    gameObjectList = loadedLevel.getObjectClasses(); //only works from within a .jar
                }
            }
            catch(Exception e){
            }

            // update toolbox
            if(camera != null){
                Toolbox.camPrefHeightSpinner.setValue(camera.prefHeight);
                Toolbox.camToleranceSpinner.setValue(camera.tolerance);
            }

            Toolbox.bg1TextField.setText(loadedLevel.levelName + "/bg1.png");
            Toolbox.bg0TextField.setText(loadedLevel.levelName + "/bg0.png");
            Toolbox.tilesheetTextField.setText(loadedLevel.levelName + "/tilesheet.png");
            Toolbox.mapWidthSpinner.setValue(loadedLevel.getWidth() - 1);
            Toolbox.mapHeightSpinner.setValue(loadedLevel.getHeight());

            // update draw area
            Map.maxWidth = loadedLevel.getWidth()*16 - 1;
            Map.maxHeight = loadedLevel.getHeight()*16;
            
            // update window
            Editor.MapScrollPane.setPreferredSize(new Dimension(Map.maxWidth - 1,Map.maxHeight));
            Editor.mapEdit.setSize(mapEdit.getSize().width, maxSize.height + 45);

            Map.background_layer = new Image[2];
            try{
                Map.background_layer[0] = ImageIO.read(new File(loadedLevel.levelName + "/bg0.png"));
                Map.background_layer[1] = ImageIO.read(new File(loadedLevel.levelName + "/bg1.png"));
            }
            catch(Exception e){
            }

            int MapWidth = loadedLevel.getWidth();
            int MapHeight = loadedLevel.getHeight();

            EditorObject[] tempObj = new EditorObject[99999];
            for(int i = 0; i < tempObj.length; i++){
                tempObj[i] = null;
            }

            int a = 0;

            for(int y = 0; y < MapHeight; y++){
                for(int x = 0; x < MapWidth; x++){
                    //Number entered in the position represents tileNumber;
                    //position of the sprite x*16, y*16

                    //get char at position X/Y in the levelLoaded string
                    char CharAtXY = loadedLevel.level.substring(MapWidth * y, loadedLevel.level.length()).charAt(x);

                    // Load objects
                    for(int i = 0; i < Toolbox.objectChooser.objectList.length; i++){
                        if(CharAtXY == Toolbox.objectChooser.objectList[i].objectChar){
                            tempObj[a] = new EditorObject(Toolbox.objectChooser.objectList[i], new Point(x, y));
                            a++;
                        }
                    }

                    // Load tiles
                    // 48 = '0' , 57 = '9'
                    if( (int)CharAtXY >= 48 && (int)CharAtXY <= 57 ){
                        GameObject tile = new GameObject("WorldTile", CharAtXY);
                        tempObj[a] = new EditorObject(tile, new Point(x, y), Integer.parseInt(""+CharAtXY));
                        a++;
                    }


                }

                Map.object = tempObj;

                // Update tile/object chooser
                try{
                    Toolbox.tileChooser.updateTileChooser();
                    Toolbox.objectChooser.updateObjectChooser();
                }
                catch(Exception e){
                    System.out.println(e);
                }

                // update Object List Editor
                ObjectListEditor.updateTable();

            }

            new File(loadedLevel.levelName + "/level").delete();
            new File(loadedLevel.levelName + "/properties").delete();
            new File(loadedLevel.levelName + "/objects").delete();

            System.out.println("Opening finished");

        }
        else{
            System.out.println("Opening cancelled...");
        }
    }


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton BackgroundButton;
    private javax.swing.JButton CameraButton;
    private javax.swing.JButton DrawButton;
    private javax.swing.JButton DrawButton1;
    public static javax.swing.JLabel EditorModeLabel;
    private javax.swing.JButton EraseButton;
    private javax.swing.JButton GridButton;
    private javax.swing.JButton MagicButton;
    public static javax.swing.JPanel MapPanel;
    public static javax.swing.JScrollPane MapScrollPane;
    private javax.swing.JButton NewButton;
    public javax.swing.JMenuItem NewMenuItem;
    private javax.swing.JButton OpenButton;
    private javax.swing.JMenuItem OpenMenuItem;
    private javax.swing.JButton SaveButton;
    private javax.swing.JButton TestButton;
    private javax.swing.JButton ToolsButton;
    public static javax.swing.JMenu WindowMenu;
    public static javax.swing.JCheckBoxMenuItem bgLayerCheckBox;
    public static javax.swing.JCheckBoxMenuItem cameraCheckBox;
    public static javax.swing.JFrame createNewMapFrame;
    public static javax.swing.JCheckBoxMenuItem gridCheckBox;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenuItem jMenuItem4;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JToolBar.Separator jSeparator2;
    private javax.swing.JToolBar.Separator jSeparator3;
    private javax.swing.JSpinner jSpinner1;
    private javax.swing.JSpinner jSpinner2;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JToolBar jToolBar1;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    public static javax.swing.JCheckBoxMenuItem toolsCheckBox;
    // End of variables declaration//GEN-END:variables

}
